// ==UserScript==
// @name			Throne Champ Organizer
// @namespace		TCO
// @description		The all in one organizer for your throne room and champion hall
// @icon            https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/843.jpg
// @version			20150000
// @delay 2000
// @priority -10
// @include        *.kingdomsofcamelot.com/*main_src.php*
// @include        *kabam.com/kingdoms-of-camelot/play*
// @resource       jqcss http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css
// @require        https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require        https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js
// @grant			unsafeWindow
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_addStyle
// @grant       GM_xmlhttpRequest
// @grant       GM_log
// @grant       GM_registerMenuCommand
// @grant       GM_getResourceText
// @grant       GM_getResourceURL
// @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TJ9YQ8S75HFEL
// ==/UserScript==

var JSON2 = JSON; 
var uW = unsafeWindow;
var Cities = {};
var mainPop;
var Tabs = {};
var ScriptButtonLabel = "TCO";
var Version = "20150000";

var UID = ""; for (var n in uW.seed.players) { UID = n.split("u")[1]; break; }
var SERVER = GetServerId();

var IMGURL = uW.stimgUrl+"img/";

var LINKCLOSED = IMGURL+"autoAttack/across_arrow.png";
var LINKOPENED = IMGURL+"autoAttack/down_arrow.png";

var URL_CASTLE_BUT = "";
var URL_CASTLE_BUT_SEL = "";

var TRSECTION = '<tr><td class="tdSectionContent">';
var TREND = '</td></tr>';

var Qualities = [ 'Simple', 'Common', 'Uncommon', 'Rare', 'Epic', 'Wondrous', 'Miraculous' ];

var TCOStyles = {
    TabColorThrone: 'red',
    TabColorChamp: 'blue',
    TabColorOther: 'yellow',
    TabColorSelected: 'green',
    WindowWidth: 650,
    WindowHeight: 400,
    TitleHeight: 21,
    BGColor: '#F7F3E6',
    TitleBGColor: '#71583A',
    HeaderTopBGColor: '#3F60AA',
    HeaderBotBGColor: '#070E1D',
    HeaderTextColor: '#FFFFFF',
    SectionTopBGColor: '#E9D9AE',
    SectionBotBGColor: '#8C7D5D',
    SectionTextColor: '#000000',
    ButtonTopBGColor: '#122349',
    ButtonBotBGColor: '#122349',
    ButtonTextColor: '#FFFFFF',
}

var TCOGlobal = {
    Update: true,
    Site: 'https://www.facebook.com',
}

var TCOGeneral = {
    NoRedX: true,
    PWidget: true,
    DragThrone: true,
    JewelsIcon: true,
    LikeBacon: false,
    BaconPhrase: "I LIKE BACON",

    ShowTabPresetsTR: true,
    ShowTabPresetsCH: true,
    ShowTabUniquesTR: true,
    ShowTabCompareTR: true,
    ShowTabPreviewTR: true,
    ShowTabPreviewCH: true,
    ShowTabLog: true,
    ShowTabCapsTR: true,
    ShowTabJewelsTR: true,
    ShowTabNews: true,
    ShowTabLinks: true,
    ShowTabTutorials: true,
    ShowTabEnhanceStatsTR: true,
    ShowTabUpgradeStatsTR: true,
    ShowTabEnhanceStatsCH: true,
    ShowTabUpgradeStatsCH: true,
    ShowTabRepairTR: true,
    ShowTabRepairCH: true,

    PutCityNum: 0,
    PutAnyCity: true,
    MaxStones: 2000000,
    Overflow: "Order",
    UpgradeFirst: true,
    UpgradeQuality: "Common",
    UpgradeManual: true,

    UseCityNum: 0,
    RetryInterval: 30,
    UseAnyCity: true,
    MinStones: 50000,
    Whisper: true,
    Inbox: false,
    PreventTokens: true,
    SafetyOn: true,
    SafetyLimit: 50000,
    RemoveTokens: false,
    MultiUpgrade: false,
    RemoveMass: true,
    RemoveForced: false,
    ThroneSafety: true,
    ThroneSafetyNum: 60,
    ChampSafety: true,
    ChampSafetyNum: 60,
}

var WinManager = {
	wins : {},    // prefix : CPopup obj

	get : function (prefix){
		var t = WinManager;
		return t.wins[prefix];
	},
  
	add : function (prefix, pop){
		var t = WinManager;
		t.wins[prefix] = pop;
		if (uW.cpopupWins == null)
			uW.cpopupWins = {};
		uW.cpopupWins[prefix] = pop;
	},
  
	delete : function (prefix){
		var t = WinManager;
		delete t.wins[prefix];
		delete uW.cpopupWins[prefix];
	}    
}

// creates a 'popup' div
// prefix must be a unique (short) name for the popup window
function CPopup(prefix, x, y, width, height, enableDrag, onClose) {
	var pop = WinManager.get(prefix);
	if (pop) {
		pop.show(false);
		return pop;
	}
	this.BASE_ZINDEX = 111111;
	// protos ...
	this.show = show;
	this.toggleHide = toggleHide;
	this.getTopDiv = getTopDiv;
	this.getMainDiv = getMainDiv;
	this.getLayer = getLayer;
	this.setLayer = setLayer;
	this.setEnableDrag = setEnableDrag;
	this.getLocation = getLocation;
	this.setLocation = setLocation;
	this.focusMe = focusMe;
	this.unfocusMe = unfocusMe;
	this.centerMe = centerMe;
	this.destroy = destroy;
	// object vars ...
	this.div = document.createElement('div');
	this.prefix = prefix;
	this.onClose = onClose;
	var t = this;
	this.div.className = 'CPopup ' + prefix + '_CPopup';
	this.div.id = prefix + '_outer';
	this.div.style.background = "#fff";
	this.div.style.zIndex = this.BASE_ZINDEX // KOC modal is 100210 ?
	this.div.style.display = 'none';
	this.div.style.width = width + 'px';
	this.div.style.height = height + 'px';
	this.div.style.position = "absolute";
	this.div.style.top = y + 'px';
	this.div.style.left = x + 'px';
	topClass = 'CPopupTop ' + prefix + '_CPopupTop';
	var m = '<TABLE cellspacing=0 width=100% height=100%><TR id="' + prefix + '_bar" class="' + topClass + '"><TD style="-moz-border-radius-topleft: 20px; border-top-left-radius: 20px;" width=99%><SPAN id="'+ prefix +'_top"></span></td>\
      <TD id=' + prefix + '_X align=right valign=middle onmouseover="this.style.cursor=\'pointer\'" style="color:#fff; background:#333; font-weight:bold; font-size:14px; padding:0px 5px;  -moz-border-radius-topright: 20px; border-top-right-radius: 20px;">X</td></tr>\
      <TR><TD height=100% valign=top class="CPopMain ' + prefix + '_CPopMain" colspan=2 id="' + prefix + '_main"></td></tr></table>';
	document.body.appendChild(this.div);
	this.div.innerHTML = m;
	document.getElementById(prefix + '_X').addEventListener('click', e_XClose, false);
	this.dragger = new CWinDrag(document.getElementById(prefix + '_bar'), this.div, enableDrag);
	this.div.addEventListener('mousedown', e_divClicked, false);
	WinManager.add(prefix, this);

	function e_divClicked() { t.focusMe(); }

	function e_XClose() {
		t.show(false);
		if (t.onClose != null) t.onClose();
	}

	function focusMe() {
		t.setLayer(5);
		for (k in uW.cpopupWins) { if (k != t.prefix) uW.cpopupWins[k].unfocusMe(); }
	}

	function unfocusMe() { t.setLayer(-5); }

	function getLocation() {
		return {
			x: parseInt(this.div.style.left),
			y: parseInt(this.div.style.top)
		};
	}

	function setLocation(loc) {
		t.div.style.left = loc.x + 'px';
		t.div.style.top = loc.y + 'px';
	}

	function destroy() {
		document.body.removeChild(t.div);
		WinManager.delete(t.prefix);
	}

	function centerMe(parent) {
		if (parent == null) {
			var coords = getClientCoords(document.body);
		} else
			var coords = getClientCoords(parent);
		var x = ((coords.width - parseInt(t.div.style.width)) / 2) + coords.x;
		var y = ((coords.height - parseInt(t.div.style.height)) / 2) + coords.y;
		if (x < 0) x = 0;
		if (y < 0) y = 0;
		t.div.style.left = x + 'px';
		t.div.style.top = y + 'px';
	}

	function setEnableDrag(tf) { t.dragger.setEnable(tf); }

	function setLayer(zi) { t.div.style.zIndex = '' + (this.BASE_ZINDEX + zi); }

	function getLayer() { return parseInt(t.div.style.zIndex) - this.BASE_ZINDEX; }

	function getTopDiv() { return document.getElementById(this.prefix + '_top'); }

	function getMainDiv() { return document.getElementById(this.prefix + '_main'); }

	function show(tf) {
		if (tf) {
			t.div.style.display = 'block';
			t.focusMe();
		} else {
			t.div.style.display = 'none';
		}
		return tf;
	}

	function toggleHide(t) {
		if (t.div.style.display == 'block') {
			return t.show(false);
		} else {
			return t.show(true);
		}
	}
}

function CWinDrag (clickableElement, movingDiv, enabled) {
	var t=this;
	this.setEnable = setEnable;
	this.setBoundRect = setBoundRect;
	this.lastX = null;
	this.lastY = null;
	this.enabled = true;
	this.moving = false;
	this.theDiv = movingDiv;
	this.body = document.body;
	this.ce = clickableElement;
	this.moveHandler = new CeventMove(this).handler;
	this.outHandler = new CeventOut(this).handler;
	this.upHandler = new CeventUp(this).handler;
	this.downHandler = new CeventDown(this).handler;
	this.clickableRect = null;
	this.boundRect = null;
	this.bounds = null;
	this.enabled = false;
	if (enabled == null) enabled = true;
	this.setEnable (enabled);

	function setBoundRect (b){    // this rect (client coords) will not go outside of current body
		this.boundRect = boundRect;
		this.bounds = null;
	}

	function setEnable (enable){
		if (enable == t.enabled) return;
		if (enable){
			clickableElement.addEventListener('mousedown',  t.downHandler, false);
			t.body.addEventListener('mouseup', t.upHandler, false);
		} else {
			clickableElement.removeEventListener('mousedown', t.downHandler, false);
			t.body.removeEventListener('mouseup', t.upHandler, false);
		}
		t.enabled = enable;
	}

	function CeventDown (that){
		this.handler = handler;
		var t = that;
		
		function handler (me){
			if (t.bounds == null){
				t.clickableRect = getClientCoords(clickableElement);
				t.bodyRect = getClientCoords(document.body);
				if (t.boundRect == null) t.boundRect = t.clickableRect;
				t.bounds = {top:10-t.clickableRect.height, bot:t.bodyRect.height-25, left:40-t.clickableRect.width, right:t.bodyRect.width-25};
			}
			if (me.button==0 && t.enabled){
				t.body.addEventListener('mousemove', t.moveHandler, true);
				t.body.addEventListener('mouseout', t.outHandler, true);
				t.lastX = me.clientX;
				t.lastY = me.clientY;
				t.moving = true;
			}
		}
	}

	function CeventUp  (that){
		this.handler = handler;
		var t = that;
		function handler (me){ if (me.button==0 && t.moving) _doneMoving(t); }
	}

	function _doneMoving (t){
		t.body.removeEventListener('mousemove', t.moveHandler, true);
		t.body.removeEventListener('mouseout', t.outHandler, true);
		t.moving = false;
	}

	function CeventOut  (that){
		this.handler = handler;
		var t = that;
		function handler (me){ if (me.button==0) t.moveHandler (me); }
	}

	function CeventMove (that){
		this.handler = handler;
		var t = that;
		
		function handler (me){
			if (t.enabled && !t.wentOut){
				var newTop = parseInt(t.theDiv.style.top) + me.clientY - t.lastY;
				var newLeft = parseInt(t.theDiv.style.left) + me.clientX - t.lastX;
				if (newTop < t.bounds.top){     // if out-of-bounds...
					newTop = t.bounds.top;
					_doneMoving(t);
				} else if (newLeft < t.bounds.left){
					newLeft = t.bounds.left;
					_doneMoving(t);
				} else if (newLeft > t.bounds.right){
					newLeft = t.bounds.right;
					_doneMoving(t);
				} else if (newTop > t.bounds.bot){
					newTop = t.bounds.bot;
					_doneMoving(t);
				}
				t.theDiv.style.top = newTop + 'px';
				t.theDiv.style.left = newLeft + 'px';
				t.lastX = me.clientX;
				t.lastY = me.clientY;
			}
		}
	}
}

function getClientCoords(e) {
	if (e == null)
		return {
			x: null,
			y: null,
			width: null,
			height: null
		};
	var x = 0,
		y = 0;
	ret = {
		x: 0,
		y: 0,
		width: e.clientWidth,
		height: e.clientHeight
	};
	while (e.offsetParent != null) {
		ret.x += e.offsetLeft;
		ret.y += e.offsetTop;
		e = e.offsetParent;
	}
	return ret;
}

var tabManager = {
	tabList : {},           // {name, tabColor, obj, div}
	currentTab : null,
  
	init : function (mainDiv){
		var t = tabManager;
		var sorter = [];
		for (k in Tabs){
			if (!Tabs[k].tabDisabled){  
				t.tabList[k] = {};
				t.tabList[k].name = k;
				t.tabList[k].tabColor = Tabs[k].tabColor?Tabs[k].tabColor:'blue';
				t.tabList[k].obj = Tabs[k];
				if (Tabs[k].tabLabel != null)
					t.tabList[k].label = Tabs[k].tabLabel;
				else
					t.tabList[k].label = k;
				if (Tabs[k].tabOrder != null)
					sorter.push([Tabs[k].tabOrder, t.tabList[k]]);
				else
					sorter.push([1000, t.tabList[k]]);
				t.tabList[k].div = document.createElement('div');
			}
		}

		sorter.sort (function (a,b){return a[0]-b[0]});
		var m = '';
		
		m += '<TABLE><TR><TD COLSPAN=50 style="height:8px; border-style: none; background: transparent;"></TD></TR><TR>';
		for (var i=0; i<sorter.length; i++) {
			var color = sorter[i][1].tabColor;
			m += '<TD align=center ><A id=nttc'+ sorter[i][1].name +' class="buttonv2 h20 '+color+'"><SPAN>'+ sorter[i][1].label +'</span></a></td>';
			if ((i+1)%9 == 0) m+='</tr><TR>';
		}
		m+='</tr></table>';  
			
		mainPop.getTopDiv().innerHTML = m;
    
		var contentDiv = document.createElement('div');
		contentDiv.id = 'tcoMain_content';
		mainDiv.appendChild(contentDiv);
		
		for (k in t.tabList) {
			document.getElementById('nttc'+ k).addEventListener('click', this.e_clickedTab, false);
			var div = t.tabList[k].div;
			div.style.display = 'none';
			div.style.height = '100%';
			contentDiv.appendChild(div);
			try {
				t.tabList[k].obj.init(div);
			} catch (e){
				div.innerHTML = "INIT ERROR: "+ e;
			}
		}
    
		if (t.currentTab == null) t.currentTab = sorter[0][1];    
		t.currentTab.div.style.display = 'block';
	},
  
	hideTab : function (){
		var t = tabManager;
		t.currentTab.obj.hide();
	},
  
	showTab : function (){
		var t = tabManager;
		t.currentTab.obj.show();
	},
    
	setTabStyle : function (Tab, selected){
		var e = document.getElementById ('nttc'+ Tab.name)
		var c = Tab.tabColor?Tab.tabColor:"blue";
		if (selected){
			e.className = 'buttonv2 h20 ' + TCOStyles.TabColorSelected;
		} else {
			e.className = 'buttonv2 h20 '+c;
		}
	},
  
	e_clickedTab : function (e){
		var t = tabManager;
		mainPop.show (true);
		if (e.target.id)
			var newTab = t.tabList[e.target.id.substring(4)];
		else
			var newTab = t.tabList[e.target.parentNode.id.substring(4)];
		if (t.currentTab.name != newTab.name){
			t.setTabStyle (t.currentTab, false);
			t.setTabStyle (newTab, true);
			t.currentTab.obj.hide ();
			t.currentTab.div.style.display = 'none';
			t.currentTab = newTab;
			newTab.div.style.display = 'block';
		}
		newTab.obj.show();
	},

}

function eventHideShow() {
	if (mainPop.toggleHide(mainPop)) {
		tabManager.showTab();
	} else {
		tabManager.hideTab();
	}
}

function createButton(label) {
	var a = document.createElement('a');
	a.className = 'button20';
	a.innerHTML = '<span style="color: #ff6">' + label + '</span>';
	return a;
}

function AddMainTabLink(text, eventListener, mouseListener) {
	var a = createButton(text);
	a.className = 'tab';
	var tabs = document.getElementById('main_engagement_tabs');
	if (!tabs) {
		tabs = document.getElementById('topnav_msg');
		if (tabs) tabs = tabs.parentNode;
	}
	if (tabs) {
		var e = tabs.parentNode;
		var gmTabs = null;
		for (var i = 0; i < e.childNodes.length; i++) {
			var ee = e.childNodes[i];
			if (ee.tagName && ee.tagName == 'DIV' && ee.className == 'tabs_engagement' && ee.id != 'main_engagement_tabs') {
				gmTabs = ee;
				break;
			}
		}
		if (gmTabs == null) {
			gmTabs = document.createElement('div');
			gmTabs.className = 'tabs_engagement';
			tabs.parentNode.insertBefore(gmTabs, tabs);
			gmTabs.style.whiteSpace = 'normal';
			gmTabs.style.width = '735px';
		}
		gmTabs.style.height = '0%';
		gmTabs.style.overflow = 'auto';
		if (gmTabs.firstChild)
			gmTabs.insertBefore(a, gmTabs.firstChild);
		else
			gmTabs.appendChild(a);
		a.addEventListener('click', eventListener, false);
		if (mouseListener != null) a.addEventListener('mousedown', mouseListener, true);
		return a;
	}
	return null;
}

function ScriptStartup () {
	var metc = getClientCoords(document.getElementById('main_engagement_tabs'));
	if (metc.width==null || metc.width==0) {
		setTimeout (ScriptStartup, 1000);
		return;
	}
	
	// initialise 
    LoadTCOGeneralOptions();

	var styles = '';
    styles += 'tr.CPopupTop td {background-color:' + TCOStyles.TitleBGColor + '; border:1px solid #000000; height: ' + TCOStyles.TitleHeight + 'px;  padding:0px; color:#FFFFFF;}';
    styles += '.CPopMain {background-color:' + TCOStyles.BGColor + '; border:1px solid #000000; -moz-box-shadow:inset 0px 0px 10px #6a6a6a; -moz-border-radius-bottomright: 20px; -moz-border-radius-bottomleft: 20px; border-bottom-right-radius: 20px; border-bottom-left-radius: 20px; font-size:11px; color:#000000}';
	styles += '.CPopup {border:5px ridge #666; opacity:1; -moz-border-radius:25px; border-radius:25px; -moz-box-shadow: 1px 1px 5px #000000;}';

    styles += '.castleBut {outline:0px; margin-left:0px; margin-right:0px; width:24px; height:26px; font-size:12px; font-weight:bold;}';
    styles += '.castleBut:hover {background-image:url("'+ URL_CASTLE_BUT_SEL +'")}';
    styles += '.castleButNon {background-image:url("'+ URL_CASTLE_BUT +'")}';
    styles += '.castleButSel {background-image:url("'+ URL_CASTLE_BUT_SEL +'")}';
    styles += '.flipImage {-moz-transform: scaleX(-1); -o-transform: scaleX(-1); -webkit-transform: scaleX(-1); transform: scaleX(-1); filter: FlipH; -ms-filter: "FlipH";}';

    styles += '.divContainer {overflow-y: scroll; max-width: ' + TCOStyles.WindowWidth + 'px; max-height: ' + (TCOStyles.WindowHeight - TCOStyles.TitleHeight) + 'px; height: ' + (TCOStyles.WindowHeight - (TCOStyles.TitleHeight * 3)) + 'px;}';
	styles += '.divTitleBar {border:0px solid; border-color:#000000; background: -moz-linear-gradient(top, ' + TCOStyles.HeaderTopBGColor + ', ' + TCOStyles.HeaderBotBGColor + '); -moz-border-radius:5px; height: 16px;border-bottom:0px solid #000000;font-weight:bold;font-size:11px;opacity:0.75;margin-left:0px;margin-right:0px;margin-top:1px;margin-bottom:0px;padding-top:1px;padding-right:10px;vertical-align:text-top;text-align:center; color:' + TCOStyles.HeaderTextColor + ';}';
    styles += '.divTitleContent {border:0px;}';
	styles += '.divSectionBar {border:0px solid; border-color:#000000; background: -moz-linear-gradient(top, ' + TCOStyles.SectionTopBGColor + ', ' + TCOStyles.SectionBotBGColor+ '); -moz-border-radius:5px; height: 16px;border-bottom:0px solid #000000;font-weight:bold;font-size:11px;opacity:0.75;margin-left:0px;margin-right:0px;margin-top:1px;margin-bottom:0px;padding-top:0px;padding-right:10px;vertical-align:text-top;text-align:center; color:' + TCOStyles.SectionTextColor + ';cursor:pointer;}';
    styles += '.divSectionContent {border:0px; display:none;}';
    styles += '.tableSectionContent {border:0px;width:100%;}';
    styles += '.tdSectionContent {border:0px;margin:0px;padding:0px;vertical-align:middle;}';

    styles += '.tcoButton {font-weight:bold;font-size:11px;border:1px solid;border-color:#000000;background: -moz-linear-gradient(top, ' + TCOStyles.ButtonTopBGColor + ', ' + TCOStyles.ButtonBotBGColor+ ');color:' + TCOStyles.ButtonTextColor + ';}';
    styles += '.tcoText {font-weight:normal;font-size:11px;border:1px solid;border-color:#000000;background-color:#DCDCDC;}';
    styles += '.tcoSelect {font-weight:normal;font-size:11px;border:1px solid;border-color:#000000;background-color:#DCDCDC;}';
    styles += '.tcoCheckBox {background-color: #DCDCDC;background: -webkit-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);background: -moz-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);background: -o-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);background: -ms-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);background: linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#fcfff4", endColorstr="#b3bead",GradientType=0 );-webkit-border-radius: 50px;-moz-border-radius: 50px;border-radius: 50px;-webkit-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);-moz-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);position: relative;}';
	
    SetCities();

	AddMainTabLink(ScriptButtonLabel, eventHideShow);

	mainPop = new CPopup ('tcoMain', 0, 0, TCOStyles.WindowWidth, TCOStyles.WindowHeight , true, function (){ tabManager.hideTab(); });
	mainPop.getMainDiv().innerHTML = '<STYLE>'+ styles +'</style>';

	tabManager.init (mainPop.getMainDiv());
}

/*********************************** TABS ***********************************/

Tabs.tcoOptions = {
	tabOrder: 100,
	tabLabel: 'Options',
	tabColor: TCOStyles.TabColorOther,
	
	init: function (div) {
		var t = Tabs.tcoOptions;
		t.mydiv = div;
	},
	
	hide: function () {},
	
	show: function () {
		var t = Tabs.tcoOptions;
		m = '';
		m += '<div class="divTitleBar">OPTIONS</div>';
		m += '<div class="divTitleContent" id=titleContent>';
        m += '<table class="tableSectionContent">';
        m += TRSECTION + '<center><a id=tcoDonateLink><img id=tcoDonateImg /></a></center>' + TREND;
        m += TRSECTION + '<input id=tcoUpdate type=checkbox ' + (TCOGlobal.Update ? 'CHECKED ' : '') + '/>Auto-Update (All Domains) <input class="tcoButton" id=tcoGetItNow type=button value="Get It Now"/>' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoNoRedX type=checkbox ' + (TCOGeneral.NoRedX ? 'CHECKED ' : '') + '/>Disable Big Red X' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoPWidget type=checkbox ' + (TCOGeneral.PWidget ? 'CHECKED ' : '') + '/>Enable Preset Widget (Refresh) <input class="tcoButton" id=tcoResetWidget type=button value="Reset Widget"/>' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoDragThrone type=checkbox ' + (TCOGeneral.DragThrone ? 'CHECKED ' : '') + '/>Draggable Throne Items' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoJewelsIcon type=checkbox ' + (TCOGeneral.JewelsIcon ? 'CHECKED ' : '') + '/>Show Jewel Icons' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoLikeBacon type=checkbox ' + (TCOGeneral.LikeBacon ? 'CHECKED ' : '') + '/>I Like Bacon? Bacon Phrase! <input class="tcoText" id=tcoBaconPhrase type=text value="' + TCOGeneral.BaconPhrase + '"/>&nbsp;<input class="tcoButton" id=tcoBaconChat type=button value="Bacon Chat"/>' + TREND;
        m += '</table>';
        m += '</div>';

        m += GenerateSectionLink("EXTRA TABS", "btnExtraTabs");
        m += '<div class="divSectionContent" id=btnExtraTabs>';
        m += '<table>';
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabPresetsTR  type=checkbox ' + (TCOGeneral.ShowTabPresetsTR ? 'CHECKED ' : '') + '/>Throne Preset' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabCompareTR  type=checkbox ' + (TCOGeneral.ShowTabCompareTR ? 'CHECKED ' : '') + '/>Throne Compare' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabPreviewTR  type=checkbox ' + (TCOGeneral.ShowTabPreviewTR ? 'CHECKED ' : '') + '/>Throne Preview' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabRepairTR  type=checkbox ' + (TCOGeneral.ShowTabRepairTR ? 'CHECKED ' : '') + '/>Throne Repair' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowEnhanceStatsTR  type=checkbox ' + (TCOGeneral.ShowTabEnhanceStatsTR ? 'CHECKED ' : '') + '/>Throne Enhance Stats' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowUpgradeStatsTR  type=checkbox ' + (TCOGeneral.ShowTabUpgradeStatsTR ? 'CHECKED ' : '') + '/>Throne Upgrade Stats' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabJewelsTR  type=checkbox ' + (TCOGeneral.ShowTabJewelsTR ? 'CHECKED ' : '') + '/>Throne Jewels' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabCapsTR  type=checkbox ' + (TCOGeneral.ShowTabCapsTR ? 'CHECKED ' : '') + '/>Throne Caps' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowUniquesTR  type=checkbox ' + (TCOGeneral.ShowTabUniquesTR ? 'CHECKED ' : '') + '/>Throne Uniques' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowPresetCH  type=checkbox ' + (TCOGeneral.ShowTabPresetsCH ? 'CHECKED ' : '') + '/>Champ Preset' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabRepairCH  type=checkbox ' + (TCOGeneral.ShowTabRepairCH ? 'CHECKED ' : '') + '/>Champ Repair' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowEnhanceStatsCH  type=checkbox ' + (TCOGeneral.ShowTabEnhanceStatsCH ? 'CHECKED ' : '') + '/>Champ Enhance Stats' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowUpgradeStatsCH  type=checkbox ' + (TCOGeneral.ShowTabUpgradeStatsCH ? 'CHECKED ' : '') + '/>Champ Upgrade Stats' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabLog  type=checkbox ' + (TCOGeneral.ShowTabLog ? 'CHECKED ' : '') + '/> Log' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabNews  type=checkbox ' + (TCOGeneral.ShowTabNews ? 'CHECKED ' : '') + '/> News' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTabLinks  type=checkbox ' + (TCOGeneral.ShowTabLinks ? 'CHECKED ' : '') + '/> Links' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoShowTutorials  type=checkbox ' + (TCOGeneral.ShowTabTutorials ? 'CHECKED ' : '') + '/>Tutorials' + TREND;
        m += '</table>';
        m += '</div>';

        m += GenerateSectionLink("SALVAGER OPTIONS", "btnSalvagerOptions");
        m += '<div class="divSectionContent" id=btnSalvagerOptions>';
        m += '<table>';
        m += TRSECTION + '<b>Put Aetherstones Into: </b><span id=tcoPutCity></span>' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoPutAnyCity type=checkbox ' + (TCOGeneral.PutAnyCity ? 'CHECKED' : '') + '/>When City Is Full, Put Aetherstones Anywhere.' + TREND;
        m += TRSECTION + 'Max Aetherstones: <input id=tcoMaxStones class="tcoText" type=text size=7 maxlength=7 value="' + TCOGeneral.MaxStones + '"/> Overflow Method: ';
        m += '<select class="tcoSelect" id=tcoOverflow>';
        if (TCOGeneral.Overflow == "order") {
            m += '<option value="Order" SELECTED>City Order</option><option value="Lowest">Lowest City</option>';
        } else {
            m += '<option value="Order">City Order</option><option value="Lowest" SELECTED>Lowest City</option>';
        }
        m += '</select>' + TREND;
        m += TRSECTION + 'Load Throne Rules From Domain: <INPUT class="tcoText" id=tcoThroneDomain type=text size=3 maxlength=3 /> <INPUT class="tcoButton" id=tcoLoadThroneDomain type=button value="Load"/>' + TREND;
        m += TRSECTION + 'Load Champ Rules From Domain: <INPUT class="tcoText" id=tcoChampDomain type=text size=3 maxlength=3 /> <INPUT class="tcoButton" id=tcoLoadChampDomain type=button value="Load"/>' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoUpgradeFirst type=checkbox ' + (TCOGeneral.UpgradeFirst ? 'CHECKED ' : '') + '/>Throne Upgrade +1 Before Deleting.  Max Throne Quality:';
        m += '<select class="tcoSelect" id=tcoUpgradeQuality>';
        for (var q in Qualities) { m += '<option value="' + Qualities[q] + '" ' + (TCOGeneral.UpgradeQuality == Qualities[q] ? 'SELECTED' : '') + '/>' + Qualities[q] + '</option>'; }
        m += '</select>' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoUpgradeManual type=checkbox ' + (TCOGeneral.UpgradeManual ? 'CHECKED ' : '') + '/>Throne Upgrade +1 On Manual Deleting.' + TREND;
        m += '</table>';
        m += '</div>';

        m += GenerateSectionLink("ENHANCE & UPGRADER OPTIONS", "btnEnhUpgOptions");
        m += '<div class="divSectionContent" id=btnEnhUpgOptions>';
        m += '<table>';
        m += TRSECTION + '<div><b>Use Aetherstones From: </b><span id=tcoUseCity></span></div>' + TREND;
        m += TRSECTION + 'Retry Interval (seconds): <input id=tcoRetryInterval class="tcoText" size=3 maxlength=3 type=text value="' + TCOGeneral.RetryInterval + '"/>' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoUseAnyCity type=checkbox ' + (TCOGeneral.UseAnyCity ? 'CHECKED ' : '') + '/>When City Is Low, Use Aetherstones Anywhere' + TREND;
        m += TRSECTION + 'Min Aetherstones: <input id=tcoMinStones class="tcoText" type=text size=7 maxlength=7 value="' + TCOGeneral.MinStones + '"/>';
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoWhisper type=checkbox ' + (TCOGeneral.Whisper ? 'CHECKED ' : '') + '/>Whisper Successful Upgrades/Enhancements' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoInbox type=checkbox ' + (TCOGeneral.Inbox ? 'CHECKED ' : '') + '/>Inbox Successful Upgrades/Enhancements' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoPreventTokens type=checkbox ' + (TCOGeneral.PreventTokens ? 'CHECKED ' : '') + '/>Prevent Automatic Token Selecting' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoSafetyOn type=checkbox ' + (TCOGeneral.SafetyOn ? 'CHECKED ' : '') + '/>Disable Manual Upgrades If Less <input id=tcoSafetyLimit size=7 maxlength=7 type=text class="tcoText" value="' + TCOGeneral.SafetyLimit + '"/> Aetherstones' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoRemoveTokens type=checkbox ' + (TCOGeneral.RemoveTokens ? 'CHECKED ' : '') + '/>Remove Tokens From Upgrade Panel' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoMultiUpgrade type=checkbox ' + (TCOGeneral.MultiUpgrade ? 'CHECKED ' : '') + '/>Add Button For Throne Multi-Uprade' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoRemoveMass type=checkbox ' + (TCOGeneral.RemoveMass ? 'CHECKED ' : '') + '/>Remove Mass Salvage' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoRemoveForced type=checkbox ' + (TCOGeneral.RemoveForced ? 'CHECKED ' : '') + '/>Remove Forced Salvage' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoThroneSafety type=checkbox ' + (TCOGeneral.ThroneSafety ? 'CHECKED ' : '') + '/>Remove Throne Salvage For First <input type=text id=tcoThroneSafetyNum size=2 maxlength=2 class="tcoText" value="' + TCOGeneral.ThroneSafetyNum + '"/> Items' + TREND;
        m += TRSECTION + '<input class="tcoCheckBox" id=tcoChampSafety type=checkbox ' + (TCOGeneral.ChampSafety ? 'CHECKED ' : '') + '/>Remove Champ Salvage For First <input type=text id=tcoChampSafetyNum size=2 maxlength=2 class="tcoText" value="' + TCOGeneral.ChampSafetyNum + '"/> Items' + TREND;
        m += '</table>';
        m += '</div>';

		t.mydiv.innerHTML = '<div class="divContainer">' + m + '</div>';

        $(".divSectionBar").click(function () { ToggleSection(this.id.split("divSectionBar")[0]); });

        new CityPicker("PutCitySel", document.getElementById("tcoPutCity"), true, t.PutCityButton, TCOGeneral.PutCityNum);
        new CityPicker("UseCitySel", document.getElementById("tcoUseCity"), true, t.UseCityButton, TCOGeneral.UseCityNum);

        $("#tcoDonateLink")
        .attr('href', 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TJ9YQ8S75HFEL')
        .attr('target', '_blank');
        $("#tcoDonateImg")
        .attr('src', 'https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif')
        .attr('alt', 'donate')
        .css('cursor', 'pointer');

        $("input.tcoCheckBox").click(function () {
            var index = this.id.split("tco")[1];
            TCOGeneral[index] = document.getElementById(this.id).checked;
            if (index == "NoRedX") { DisableAnimation(TCOGeneral.NoRedX); }
            SaveTCOGeneralOptions();
        });

        $("input.tcoText").change(function() {
            if (this.id == "tcoThroneDomain" || this.id == "tcoChampDomain" ) return;
            var index = this.id.split("tco")[1];
            var thisValue = document.getElementById(this.id).value;
            if (index == "RetryInterval" && parseInt(thisValue) < 15) {
                thisValue = 15;
                document.getElementById(this.id).value = 15;
            }
            TCOGeneral[index] = thisValue;
            SaveTCOGeneralOptions();
        });

        $("select.tcoSelect").change(function() {
            var index = this.id.split("tco")[1];
            TCOGeneral[index] = document.getElementById(this.id).value;
            SaveTCOGeneralOptions();
        });

        $("#tcoBaconChat").click(function() {
            //sendChat("BACON PHRASE: " + TCOGeneral.BaconPhrase);
            alert('bacon chat');
        });

        $("#tcoGetItNow").click(function() {
            //tcoAutoUpdater.call(true,true);
            alert('updating now');
        });

        $('#tcoResetWidget').click(function () {
            //resetGuardWidget();
            //resetPresetWidget();
            alert('reseting widgets');
        });
        
        $("#tcoLoadThroneDomain").click(function () {
            //var d = $("#tcoThroneDomain").val();
            //if (d != null) TRloadSalvageData(d);
            alert('loading throne domain');
        });

        $("#tcoLoadChampDomain").click(function () {
            //var d = $("#tcoChampDomain").val();
            //if (d != null) CHloadSalvageData(d);
            alert('loading champ domain');
        });


	},

    PutCityButton: function (city, x, y) {
        TCOGeneral.PutCityNum = city.idx;
        SaveTCOGeneralOptions();
    },

    UseCityButton: function (city, x, y) {
        TCOGeneral.UseCityNum = city.idx;
        SaveTCOGeneralOptions();
    },


}

Tabs.tcoThroneUpgrade = {
	tabOrder: 200,
	tabLabel: 'Upgrade',
	tabColor: TCOStyles.TabColorThrone,
	
	init: function (div) {
		var t = Tabs.tcoThroneUpgrade;
		t.mydiv = div;
	},
	
	hide: function () {},
	
	show: function () {
		var t = Tabs.tcoThroneUpgrade;
		m = '';

		t.mydiv.innerHTML = '<div class="divContainer">' + m + '</div>';

    },
}


Tabs.newTab = {
	tabOrder: 20000,
	tabLabel: 'newTab',
	tabColor: TCOStyles.TabColorOther,
	
	init: function (div) {
		var t = Tabs.newTab;
		t.mydiv = div;
	},
	
	hide: function () {},
	
	show: function () {
		var t = Tabs.newTab;
		m = '';

		t.mydiv.innerHTML = '<div class="divContainer">' + m + '</div>';

    },
}

/***********************************************************************/

ScriptStartup();


function ToggleSection(sectionIDName) {
    /* function that opens and closed a section of the bot */
    var sectionDivs = document.getElementsByClassName("divSectionContent");
    var divSection = document.getElementById(sectionIDName);
    for (var divIndex = 0; divIndex < sectionDivs.length; divIndex++) {
        if (divSection.id == sectionDivs[divIndex].id) continue;        
        if (sectionDivs[divIndex].style.display == "block") {
            sectionDivs[divIndex].style.display = "none";
            document.getElementById(sectionDivs[divIndex].id + 'Arrow').src = LINKCLOSED;
        }        
    }
    if (divSection.style.display == "block")
    { 
        divSection.style.display = "none";
        document.getElementById(divSection.id + 'ArrowFlip').src = LINKCLOSED;
        document.getElementById(divSection.id + 'Arrow').src = LINKCLOSED;
    } else {
        divSection.style.display = "block";
        document.getElementById(divSection.id + 'ArrowFlip').src = LINKOPENED;
        document.getElementById(divSection.id + 'Arrow').src = LINKOPENED;
    }
}

function GenerateSectionLink(sectionTitle, sectionIDName) {
    /* function to create a section link to avoid repeat coding */
    var sectionLink = '';
    sectionLink += '<div class="divSectionBar" id="' + sectionIDName + 'divSectionBar">'
    sectionLink += '<img id="' + sectionIDName + 'ArrowFlip" height="10" src="' + LINKCLOSED + '" class="flipImage">';
    sectionLink += '&nbsp;' + sectionTitle + '&nbsp;';
    sectionLink += '<img id="' + sectionIDName + 'Arrow" height="10" src="' + LINKCLOSED + '">';
    sectionLink += '</div>';
    return sectionLink;
}

var tcoAutoUpdater = {
    id: "TCO",
    GoogleCodeURL:'https://tco.googlecode.com/svn/trunk/TCO.user.js',
    name: 'Throne Champ Organizer',
    homepage: 'https://code.google.com/p/tco/',
    version: Version,
    secure: true,
    call: function(secure,response) {logit("Checking for "+this.name+" Update!"+(secure ? ' (SSL)' : ' (plain)'));
        this.secure = secure;
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'http'+(secure ? 's' : '')+'://'+this.GoogleCodeURL,
            onload: function(xpr) {AutoUpdater.compare(xpr,response);},
            onerror: function(xpr) {if (secure) {AutoUpdater.call(false,response);} else {AutoUpdater.compare({responseText:""},response);}}
        });
    },
    
    compareVersion: function(r_version, l_version) {
            var r_parts = r_version.split(''),
            l_parts = l_version.split(''),
            r_len = r_parts.length,
            l_len = l_parts.length,
            r = l = 0;
            for(var i = 0, len = (r_len > l_len ? r_len : l_len); i < len && r == l; ++i) {
                r = +(r_parts[i] || '0');
                l = +(l_parts[i] || '0');
            }
            return (r !== l) ? r > l : false;
    },
    
    compare: function(xpr,response) {
        this.xversion=/\/\/\s*@version\s+(.+)\s*\n/i.exec(xpr.responseText);   
        if (this.xversion) this.xversion = this.xversion[1];
        else {
            if (response) {
                //$(document.querySelector("#org_dialog")).dialog("close");
                uW.Modal.showAlert('<div align="center">Unable to check for updates to '+this.name+'.<br>Please change the update options or visit the<br><a href="'+this.homepage+'" target="_blank">script homepage</a></div>');
            }
            logit("Unable to check for updates :(");
            return;
        }
        this.xrelnotes=/\/\/\s*@releasenotes\s+(.+)\s*\n/i.exec(xpr.responseText);   
        if (this.xrelnotes) this.xrelnotes = this.xrelnotes[1];
        var updated = this.compareVersion(this.xversion, this.version);   
        if (updated) {
            logit('New Version Available!');                  
            var body = '<BR><DIV align=center><FONT size=3><B>New version ' + this.xversion + ' is available!</b></font></div><BR>';
            if (this.xrelnotes) body+='<BR><div align="center" style="border:0;width:470px;height:120px;max-height:120px;overflow:auto"><b>New Features!</b><p>'+this.xrelnotes+'</p></div><BR>';
            body+='<BR><DIV align=center><a class="gemButtonv2 green" id="doBotUpdate">Update</a></div>';
            //$(document.querySelector("#org_dialog")).dialog("close");
            this.ShowUpdate(body);
        }
        else
        {
            //$(document.querySelector("#org_dialog")).dialog("close");
            logit("No updates available :(");
            if (response) uW.Modal.showAlert('<div align="center">No updates available for '+this.name+' at this time.</div>');
        }         
    },
    
    check: function() {
        var now = unixTime();
        var lastCheck = 0;
        if (GM_getValue('updated_'+this.id, 0)) lastCheck = parseInt(GM_getValue('updated_'+this.id, 0));
        if (now > (lastCheck + 60*60*12)) this.call(true,false);
    },
    
    ShowUpdate: function (body) {
        var now = unixTime();     
        uW.cm.ModalManager.addMedium({
            title: this.name,
            body: body,
            closeNow: false,
            close: function () {
                setTimeout (function (){GM_setValue('updated_'+AutoUpdater.id, now);}, 0);
                uW.cm.ModalManager.closeAll();
            },
            "class": "Warning",
            curtain: false,
            width: 500,
            height: 700,
            left: 140,
            top: 140
        });
        document.getElementById('doBotUpdate').addEventListener ('click', this.doUpdate, false);   
    },

    doUpdate: function () {
        uW.cm.ModalManager.closeAll();
        uW.cm.ModalManager.close();
        var now = unixTime();
        GM_setValue('updated_'+AutoUpdater.id, now);
        location.href = 'http'+(AutoUpdater.secure ? 's' : '')+'://'+AutoUpdater.GoogleCodeURL;
    },

};


function GetServerId() {
    if (SERVER == null){
        var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
        if (m)
            SERVER = m[1];
        else
            SERVER = '??';
    }
    return SERVER;
}

function matTypeof (v){
    if (typeof (v) == 'object'){
        if (!v)
            return 'null';
        else if (v.constructor.toString().indexOf("Array")>=0 && typeof(v.splice)=='function')
            return 'array';
        else return 'object';
    }
    return typeof (v);
}

function CityPicker (id, span, dispName, notify, selbut){
    function ButHandler (t) {
        var that = t;

        function clickedCityBut (e){
            if (that.selected != null) that.selected.className = "castleBut castleButNon";
            that.city = Cities.cities[e.target.id.substr(that.prefixLen)];
            if (that.dispName) document.getElementById(that.id+'cname').innerHTML = that.city.name;
            e.target.className = "castleBut castleButSel";
            that.selected = e.target;
            if (that.coordBoxX){
                that.coordBoxX.value = that.city.x;
                that.coordBoxY.value = that.city.y;
                var evt = document.createEvent("HTMLEvents");
                evt.initEvent('change', true, true ); // event
                // type,bubbling,cancelable
                that.coordBoxX.dispatchEvent(evt);
                that.coordBoxY.dispatchEvent(evt);
                that.coordBoxX.style.backgroundColor = '#ffffff';
                that.coordBoxY.style.backgroundColor = '#ffffff';
            }
            if (that.notify != null) that.notify(that.city, that.city.x, that.city.y);
        }

        this.clickedCityBut = clickedCityBut;
    }

    function selectBut (idx){
        document.getElementById(this.id+'_'+idx).click();
    }

    function bindToXYboxes (eX, eY){
        function CboxHandler (t){
            var that = t;
            this.eventChange = eventChange;
            if (that.city){
                eX.value = that.city.x;
                eY.value = that.city.y;
            }
            function eventChange (){
                var xValue=that.coordBoxX.value.trim();
                var xI=/^\s*([0-9]+)[\s|,|-|.]+([0-9]+)/.exec(xValue);
                if(xI) {
                    that.coordBoxX.value=xI[1]
                    that.coordBoxY.value=xI[2]
                }
                var x = parseInt(that.coordBoxX.value, 10);
                var y = parseInt(that.coordBoxY.value, 10);
                if (isNaN(x) || x<0 || x>750){
                    that.coordBoxX.style.backgroundColor = '#ff8888';
                    return;
                }
                if (isNaN(y) || y<0 || y>750){
                    that.coordBoxY.style.backgroundColor = '#ff8888';
                    return;
                }
                that.coordBoxX.style.backgroundColor = '#ffffff';
                that.coordBoxY.style.backgroundColor = '#ffffff';
                if (that.notify != null) that.notify (null, x, y);
            }
            return false;
        }
        this.coordBoxX = eX;
        this.coordBoxY = eY;
        var bh = new CboxHandler(this);
        eX.maxLength=8;
        eY.maxLength=3;
        eX.style.width='2em';
        eY.style.width='2em';
        eX.addEventListener('change', bh.eventChange, false);
        eY.addEventListener('change', bh.eventChange, false);
    }

    this.selectBut = selectBut;
    this.bindToXYboxes = bindToXYboxes;
    this.coordBoxX = null;
    this.coordBoxY = null;
    this.id = id;
    this.dispName = dispName;
    this.prefixLen = id.length+1;
    this.notify = notify;
    this.selected = null;
    this.city = null;
    var m = '';
    for (var i=0; i<Cities.cities.length; i++) m += '<INPUT class="castleBut castleButNon" id="'+ id +'_'+ i +'" value="'+ (i+1) +'" type=button />';
    if (dispName) m += ' &nbsp; <SPAN style="display:inline-block; width:85px; font-weight:bold;" id='+ id +'cname' +'></span>';
    span.innerHTML = m;
    var handler = new ButHandler(this);
    for (var i=0; i<Cities.cities.length; i++) document.getElementById (id+'_'+i).addEventListener('click', handler.clickedCityBut, false);
    if (selbut != null) this.selectBut(selbut);
};

function SetCities(){
    Cities.numCities = uW.seed.cities.length;
    Cities.cities = [];
    Cities.byID = {};
    for (i=0; i<Cities.numCities; i++){
        city = {};
        city.idx = i;
        city.id = parseInt(uW.seed.cities[i][0]);
        city.name = uW.seed.cities[i][1];
        city.x = parseInt(uW.seed.cities[i][2]);
        city.y = parseInt(uW.seed.cities[i][3]);
        city.tileId = parseInt(uW.seed.cities[i][5]);
        city.provId = parseInt(uW.seed.cities[i][4]);
        Cities.cities[i] = city;
        Cities.byID[uW.seed.cities[i][0]] = city;
    }
}

function sendChat (msg){  //Simple method, as if it were typed in thru DOM
    $(document.querySelector("#mod_comm_input")).val(msg);
    uW.Chat.sendChat ();
}

function rectime(secs) {
    var min = Math.floor((secs)/60);
    var sec = Math.ceil(secs - (min * 60));

    if (sec < 10) {sec = "0" + sec;}
    return  min + ':' + sec;
}

var WithAnim = null;
if (uW.cm && uW.cm.ThronePanelView) WithAnim = uW.cm.ThronePanelView.statusAnim;

function NoAnim(result) {
    if (result == "success")
    {
        var item_name = $("#thronePanelName").html();
        var attempt_type = $("div.thronePanelContainer").find("li.selected").html();

        var msg = "Manual ";
        if (attempt_type)
            msg += attempt_type;
        else
            msg += "upgrade/enhance";

        msg += " successful.";

        if (item_name) msg += "  Item: " + item_name;

        SuccessLog(msg);

        if (WithAnim) WithAnim(result);
    }
    $("div.thronePanelItemContainer").append("<div>" + result + "</div>");
}

function DisableAnimation(disable) {
    if (disable) { // override the success failure animations
        uW.cm.ThronePanelView.statusAnim = NoAnim;
    } else {
        if (WithAnim) uW.cm.ThronePanelView.statusAnim = WithAnim;
    }
}

function SaveTCOGeneralOptions () {
    setTimeout (function (){GM_setValue ('TCOGeneralOptions_' + UID + '_' + SERVER, JSON2.stringify(TCOGeneral));}, 0);
}

function LoadTCOGeneralOptions () {
    s = GM_getValue ('TCOGeneralOptions_' + UID + '_' + SERVER);
    if (s != null){
        opts = JSON2.parse (s);
        for (k in opts){
            if (matTypeof(opts[k]) == 'object')
                for (kk in opts[k])
                    TCOGeneral[k][kk] = opts[k][kk];
            else
                TCOGeneral[k] = opts[k];
        }
    }
}